/*
 * > /*
 >  * INSANE - Interactive Structural Analysis Environment
 >  *
 >  * Copyright (C) 2003-2004
 >  * Universidade Federal de Minas Gerais
 >  * Escola de Engenharia
 >  * Departamento de Engenharia de Estruturas
 >  *
 >  * Author's email :     insane@dees.ufmg.br
 >  * Author's Website :   http://www.dees.ufmg.br/insane
 >  *
 >  * This program is free software; you can redistribute it and/or
 >  * modify it under the terms of the GNU General Public License
 >  * as published by the Free Software Foundation; either version 2
 >  * of the License, or any later version.
 >  *
 >  * This program is distributed in the hope that it will be useful,
 >  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 >  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 >  * GNU General Public License for more details.
 >  *
 >  * You should have received a copy of the GNU General Public License
 >  * along with this program; if not, write to the Free Software
 >  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-
 > 1307, USA.
 *
 */
package br.ufmg.dees.insane.ui.rich.learn.learn_controller;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import br.ufmg.dees.insane.draw.ArrowDraw;
import br.ufmg.dees.insane.draw.ArrowLineDraw;
import br.ufmg.dees.insane.draw.AxisDraw;
import br.ufmg.dees.insane.draw.DisplaceDraw;
import br.ufmg.dees.insane.draw.Draw;
import br.ufmg.dees.insane.draw.LiberationDraw;
import br.ufmg.dees.insane.draw.LineArrowDraw;
import br.ufmg.dees.insane.draw.LineDraw;
import br.ufmg.dees.insane.draw.PointDraw;
import br.ufmg.dees.insane.draw.SpringDraw;
import br.ufmg.dees.insane.draw.StringDraw;
import br.ufmg.dees.insane.draw.SupportDraw;
import br.ufmg.dees.insane.model.disc.driver.StructuralMech;
import br.ufmg.dees.insane.model.disc.element.Element;
import br.ufmg.dees.insane.model.disc.element.FrameElement;
import br.ufmg.dees.insane.model.disc.element.ParametricElement;
import br.ufmg.dees.insane.model.disc.element.force.ElementForce;
import br.ufmg.dees.insane.model.disc.element.force.ElementSide;
import br.ufmg.dees.insane.model.disc.element.force.Side;
import br.ufmg.dees.insane.model.disc.fem.FemModel;
import br.ufmg.dees.insane.model.disc.node.Node;
import br.ufmg.dees.insane.model.disc.pointforce.PointForce;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.IView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.LearnView;
import br.ufmg.dees.insane.ui.rich.learn.learn_view.ParElementDraw;
import br.ufmg.dees.insane.util.IPoint3d;

/**
 * 
 * @author Moreira, Renata & Pitangueira, Roque
 * @since May 2005
 */
public class  LearnController implements Controller{
	
	    protected FemModel model;
	    protected IView view;
	    protected StructuralMech driver;
	    protected ArrayList<Object> selection = new ArrayList<Object>();
	 
	    protected ArrayList<Draw> nodes = new ArrayList<Draw>();
		protected ArrayList<Draw> felements = new ArrayList<Draw>();
		protected ArrayList<Draw> pelements = new ArrayList<Draw>();
		
		protected ArrayList<Draw> supports = new ArrayList<Draw>();
		protected ArrayList<Draw> springs = new ArrayList<Draw>();
		protected ArrayList<Draw> nodalLoads = new ArrayList<Draw>();
		protected ArrayList<Draw> displaces = new ArrayList<Draw>();
		
		protected ArrayList<Draw> localAxis = new ArrayList<Draw>();
		protected ArrayList<Draw> concForces = new ArrayList<Draw>();
		protected ArrayList<Draw> concForcesPoints = new ArrayList<Draw>();
		protected ArrayList<Draw> liberations = new ArrayList<Draw>();
		protected ArrayList<Draw> preStrains = new ArrayList<Draw>();
		protected ArrayList<Draw> distForces = new ArrayList<Draw>();
		protected ArrayList<Draw> tempChanges = new ArrayList<Draw>();
		protected ArrayList<Draw> iniEqForces = new ArrayList<Draw>();
		protected ArrayList<Draw> elasticConnections = new ArrayList<Draw>();
		
		protected ArrayList<Draw> gaussMarks = new ArrayList<Draw>();
	 
	    /**
	     * The constructor method xyplot_controller, inicializes xymodel
	     * @param model a model
	     * @see XYPlotInterface
	     */
	    public LearnController(FemModel model) {
	        this.model = model;
	    }
	    /**
	     * The constructor method EquationsController, inicializes XYPlot, IView 
	     * @param model a XYPlot model
	     * @param vs a IView
	     * @see XYPlotInterface
	     */
	    public LearnController(FemModel model, IView vs) {
	        this.model = model;
	        this.view = vs;
	    }
	    
	    /**
	     * The constructor method EquationsController, inicializes XYPlot, IView 
	     * @param model a XYPlot model
	     * @param vs a IView
	     * @see XYPlotInterface
	     */
	    public LearnController(FemModel model, IView vs, StructuralMech dr) {
	        this.model = model;
	        this.view = vs;
	        this.driver = dr;
	    }
	    
	    /**
	     * The constructor method EquationsController, inicializes IView 
	     * @param vs a IView
	     * @see Interface
	     */
	    public LearnController(IView vs) {
	        this.view = vs;
	    }

	    
	    public LearnController() {}

//	**************************************************************************************

	    /**
	     * The method set LearnModel model
	     * @param newModel a new LearnModel model 
	     */
	    public void setModel(FemModel newModel) {
	        this.model = newModel;
	    }

	    
	    public FemModel getModel( ) {
	        return this.model;
	    }

	    /**
	     * The method set LearnView 
	     * @param newView a new LearnView 
	     */
	    public IView getView( ) {
	        return this.view;
	    }
	    
	    /**
	     * The method get LearnView 
	     * @param newView a new LearnView 
	     */
	    public void setView(LearnView newView){
	        this.view = newView;
	    }
	    
	    
	    /**
	     * The method set LearnView 
	     * @param newView a new LearnView 
	     */
	    public StructuralMech getDriver( ) {
	        return this.driver;
	    }
	    
	    /**
	     * The method get LearnView 
	     * @param newView a new LearnView 
	     */
	    public void setDriver(StructuralMech dr){
	        this.driver = dr;
	    }
	
	    public List removeSelection() {
	        
	        ArrayList<Object> sel = new ArrayList<Object>();
			PointDraw pd;
	        LineDraw ld;
	        int index;
	        
	        ListIterator pts = nodes.listIterator();
	        while(pts.hasNext()) {
	            pd = (PointDraw)pts.next();
	            if (pd.isSelected()) {
					Node p = (Node)pd.getRepresents();
					index = selection.indexOf(pd.getRepresents());
					selection.remove(index);
	                model.remove(p);
	                sel.add(p);
	            }
	        }
	        
	        ListIterator gpts = nodes.listIterator();
	        while(gpts.hasNext()) {
	            pd = (PointDraw)gpts.next();
	            if (pd.isSelected()) {
					Node p = (Node)pd.getRepresents();
					index = selection.indexOf(pd.getRepresents());
					selection.remove(index);
	                model.remove(p);
	                sel.add(p);
	            }
	        }
	        
			ListIterator lns = felements.listIterator();
			while(lns.hasNext()) {
				ld = (LineDraw)lns.next();
				if (ld.isSelected()){
					Element l = (Element)ld.getRepresents();
					index = selection.indexOf(ld.getRepresents());
					selection.remove(index);
					model.remove(l);
					sel.add(l);
				}
			}
			ListIterator pes = pelements.listIterator();
			while(pes.hasNext()) {
				ld = (LineDraw)pes.next();
				if (ld.isSelected()){
					Element l = (Element)ld.getRepresents();
					index = selection.indexOf(ld.getRepresents());
					selection.remove(index);
					model.remove(l);
					sel.add(l);
				}
			}
			this.compose();
			
			return sel;
			
	    }
	    
	    public void compose() {
			
			this.removeAll();
			
			//Filling the "nodes", "supports", "springs" and "nodalLoads" lists
			ListIterator femnodes = model.getNodesList().listIterator();
			
			Node node;
			Point2D po;
			Point p;
			while (femnodes.hasNext()) {
				node = (Node)femnodes.next();
				po = new Point2D.Double(node.getCoord().x, node.getCoord().y);
				p = view.getDrawingArea().getViewPoint(po);
				nodes.add(new PointDraw(p, node));
				
				//adding supports and springs
				boolean Rdx = node.getRestraint(0);
				boolean Rdy = node.getRestraint(1);
				//boolean Rdz = node.getRestraint(2);
				//boolean Rrx = node.getRestraint(3);
				//boolean Rry = node.getRestraint(4);
				boolean Rrz = node.getRestraint(5);
				
				double Kx = node.getSpring(0);
				double Ky = node.getSpring(1);
				//double Kz = node.getSpring(2);
				//double Krx = node.getSpring(3);
				//double Kry = node.getSpring(4);
				double Krz = node.getSpring(5);
				
				if (Rdx && !Rdy && !Rrz && Kx==0 && Ky==0 && Krz==0) {
					Draw draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz==0) {
					Draw draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
					Draw draw = new SupportDraw.Z();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz==0) {
					Draw draw = new SupportDraw.XY();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && !Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
					Draw draw = new SupportDraw.YZ();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
					Draw draw = new SupportDraw.YZ();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && Rdy && Rrz && Kx==0 && Ky==0 && Krz==0) {
					Draw draw = new SupportDraw.XYZ();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky==0 && Krz==0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz==0) {
					Draw draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
					Draw draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky!=0 && Krz==0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky==0 && Krz!=0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz!=0) {
					Draw draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw); 
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && !Rrz && Kx!=0 && Ky!=0 && Krz!=0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz==0) {
					Draw draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && !Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
					Draw draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
					Draw draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && Rdy && !Rrz && Kx!=0 && Ky==0 && Krz==0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && Rrz && Kx!=0 && Ky==0 && Krz==0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SupportDraw.Z();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && Rrz && Kx==0 && Ky!=0 && Krz==0) {
					Draw draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SupportDraw.Z();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && Rdy && !Rrz && Kx==0 && Ky==0 && Krz!=0) {
					Draw draw = new SupportDraw.XY();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && !Rdy && Rrz && Kx==0 && Ky!=0 && Krz==0) {
					Draw draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SupportDraw.YZ();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && Rdy && Rrz && Kx!=0 && Ky==0 && Krz==0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SupportDraw.YZ();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (Rdx && !Rdy && !Rrz && Kx==0 && Ky!=0 && Krz!=0) {
					Draw draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(-Math.toRadians(90) + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && Rdy && !Rrz && Kx!=0 && Ky==0 && Krz!=0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SupportDraw.Y();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Rz();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				} else if (!Rdx && !Rdy && Rrz && Kx!=0 && Ky!=0 && Krz==0) {
					Draw draw = new SpringDraw.Dx();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(90)*2 + node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SpringDraw.Dy();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					draw = new SupportDraw.Z();
					draw.setRepresents(node);
					draw.setAngle(node.getAngle()*Math.PI/180);
					this.add(draw);
					
				}//end of adding supports
				
				//Adding nodal loads
				//Fx loads
				if (node.getForce(0) != 0) {
					Draw draw = new ArrowDraw.Out();
					draw.setRepresents(node);
					((ArrowDraw)draw).setValue(node.getForce(0));
					draw.setAngle(node.getAngle()*Math.PI/180);
					//draw.setLabel(String.valueOf(node.getForce(0)));
					this.add(draw);
				}
				//Fy loads
				if (node.getForce(1) != 0) {
					Draw draw = new ArrowDraw.Out();
					draw.setRepresents(node);
					((ArrowDraw)draw).setValue(node.getForce(1));
					draw.setAngle(Math.toRadians(90) + node.getAngle()*Math.PI/180);
					//draw.setLabel(String.valueOf(node.getForce(1)));
					this.add(draw);
				}
				//Mz loads
				if (node.getForce(5) != 0) {
					Draw draw = new ArrowDraw.AntiClockwise();
					draw.setRepresents(node);
					((ArrowDraw)draw).setValue(node.getForce(5));
					//draw.setLabel(String.valueOf(node.getForce(5)));
					this.add(draw);
				}
				//End of adding nodalLoads
				
				//Adding prescribed displacement
				double Ddx = node.getPreDisplacement(0);
				double Ddy = node.getPreDisplacement(1);
				//double Ddz = node.getPreDisplacement(2);
				//double Drx = node.getPreDisplacement(3);
				//double Dry = node.getPreDisplacement(4);
				double Drz = node.getPreDisplacement(5);
				if (Ddx!=0) {
					Draw draw = new DisplaceDraw.Linear();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(node.getAngle()));
					((DisplaceDraw)draw).setValue(Ddx);
					this.add(draw);
				}
				if (Ddy!=0) {
					Draw draw = new DisplaceDraw.Linear();
					draw.setRepresents(node);
					draw.setAngle(Math.toRadians(node.getAngle() +90));
					((DisplaceDraw)draw).setValue(Ddy);
					this.add(draw);
				}
				if (Drz!=0) {
					Draw draw = new DisplaceDraw.Angular();
					draw.setRepresents(node);
					((DisplaceDraw)draw).setValue(Drz);
					this.add(draw);
				}//end of add prescribed displacement
				
			}
			
			//Filling the "felements", "localAxis", "liberations", "concForces", "concForcesPoints",
			// "preStrains", "distForces", "tempChanges", "iniEqForces" and "elasticConnections" lists
			ListIterator elms = model.getElementsList().listIterator();
			Element elm;
			Point p1;
			Point p2;
			while (elms.hasNext()) {
				elm = (Element)elms.next();
				if (elm instanceof FrameElement) {
					FrameElement felm = (FrameElement)elm;
					
					node = felm.getInitialNode();
					po = new Point2D.Double(node.getCoord().x, node.getCoord().y);
					p1 = view.getDrawingArea().getViewPoint(po);
					node = felm.getFinalNode();
					po = new Point2D.Double(node.getCoord().x, node.getCoord().y);
					p2 = view.getDrawingArea().getViewPoint(po);
					felements.add(new LineDraw(p1, p2, felm));
					
					//Setting the variables in (initial node) and fn (final node)
					Node in = felm.getInitialNode();
					Node fn = felm.getFinalNode();
					
					//Calculating the angle between local axis and global axis and its sine and cosine
					double elmAngle = 0;
					Point2D in2d = new Point2D.Double(in.getCoord().x, in.getCoord().y);
					Point2D fn2d = new Point2D.Double(fn.getCoord().x, fn.getCoord().y);
					in2d = view.getDrawingArea().getViewPoint(in2d);
					fn2d = view.getDrawingArea().getViewPoint(fn2d);
					
					if (fn.getCoord().x > in.getCoord().x) {
						elmAngle = -Math.atan((fn2d.getY() - in2d.getY()) / (fn2d.getX() - in2d.getX()));
					} else if (fn.getCoord().x < in.getCoord().x) {
						elmAngle = -Math.atan((fn2d.getY() - in2d.getY()) / (fn2d.getX() - in2d.getX())) + Math.toRadians(180);
					} else if ((fn.getCoord().x==in.getCoord().x) && (fn.getCoord().y>in.getCoord().y)) {
						elmAngle = Math.toRadians(90);
					} else if ((fn.getCoord().x==in.getCoord().x) && (fn.getCoord().y<in.getCoord().y)) {
						elmAngle = Math.toRadians(-90);
					}
					
					//Adding Local Axis
					Draw draw2 = new AxisDraw();
					draw2.setRepresents(felm);
					draw2.setAngle(elmAngle);
					draw2.setLocation(p1);
					((AxisDraw)draw2).setLabel1("X");
					((AxisDraw)draw2).setLabel2("Y");
					localAxis.add(draw2);
					
					//Adding liberations
					//Dx1 liberation
					if (felm.getLiberation(0) && !felm.getLiberation(1) && !felm.getLiberation(5)){
						Draw draw = new LiberationDraw.X();
						draw.setRepresents(elm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						liberations.add(draw);
					}
					//Dy1 liberation
					if (!felm.getLiberation(0) && felm.getLiberation(1) && !felm.getLiberation(5)){
						Draw draw = new LiberationDraw.Y();
						draw.setRepresents(elm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						liberations.add(draw);
					}
					//Rz1 liberation
					if (!felm.getLiberation(0) && !felm.getLiberation(1) && felm.getLiberation(5)){
						Draw draw = new LiberationDraw.Z();
						draw.setRepresents(elm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						liberations.add(draw);
					}
					//Dx1 and Dy1 liberation
					if (felm.getLiberation(0) && felm.getLiberation(1) && !felm.getLiberation(5)){
						Draw draw = new LiberationDraw.XY();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						liberations.add(draw);
					}
					//Dx1 and Rz1 liberation
					if (felm.getLiberation(0) && !felm.getLiberation(1) && felm.getLiberation(5)){
						Draw draw = new LiberationDraw.XZ();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						liberations.add(draw);
					}
					//Dy1 and Rz1 liberation
					if (!felm.getLiberation(0) && felm.getLiberation(1) && felm.getLiberation(5)){
						Draw draw = new LiberationDraw.YZ();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						liberations.add(draw);
					}
					//Dx1, Dy1 and Rz1 liberation
					if (felm.getLiberation(0) && felm.getLiberation(1) && felm.getLiberation(5)){
						Draw draw = new LiberationDraw.XYZ();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						liberations.add(draw);
					}
					
					//Dx2 liberation
					if (felm.getLiberation(6) && !felm.getLiberation(7) && !felm.getLiberation(11)){
						Draw draw = new LiberationDraw.X();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(180));
						draw.setLocation(p2);
						liberations.add(draw);
					}
					//Dy2 liberation
					if (!felm.getLiberation(6) && felm.getLiberation(7) && !felm.getLiberation(11)){
						Draw draw = new LiberationDraw.Y();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(180));
						draw.setLocation(p2);
						liberations.add(draw);
					}
					//Rz2 liberation
					if (!felm.getLiberation(6) && !felm.getLiberation(7) && felm.getLiberation(11)){
						Draw draw = new LiberationDraw.Z();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(180));
						draw.setLocation(p2);
						liberations.add(draw);
					}
					//Dx2 and Dy2 liberation
					if (felm.getLiberation(6) && felm.getLiberation(7) && !felm.getLiberation(11)){
						Draw draw = new LiberationDraw.XY();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(180));
						draw.setLocation(p2);
						liberations.add(draw);
					}
					//Dx2 and Rz2 liberation
					if (felm.getLiberation(6) && !felm.getLiberation(7) && felm.getLiberation(11)){
						Draw draw = new LiberationDraw.XZ();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(180));
						draw.setLocation(p2);
						liberations.add(draw);
					}
					//Dy2 and Rz2 liberation
					if (!felm.getLiberation(6) && felm.getLiberation(7) && felm.getLiberation(11)){
						Draw draw = new LiberationDraw.YZ();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(180));
						draw.setLocation(p2);
						liberations.add(draw);
					}
					//Dx2, Dy2 and Rz2 liberation
					if (felm.getLiberation(6) && felm.getLiberation(7) && felm.getLiberation(11)){
						Draw draw = new LiberationDraw.XYZ();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(180));
						draw.setLocation(p2);
						liberations.add(draw);
					}
					//End of adding liberations
					
					//Adding elastic connections
					//if (felm.getMaterial() instanceof MSpring) {
					//	MSpring mat = (MSpring)felm.getMaterial();
					//}
					//End of adding elastic connections
					
					//Adding concentrated forces
					ListIterator cf = felm.getElmPointForcesList().listIterator();
					while (cf.hasNext()) {
						PointForce force = (PointForce)cf.next();
						
						//Setting the application point of this concentrated force
						double cos2 = (fn.getCoord().x - in.getCoord().x) / felm.getLength();
						double sin2 = (fn.getCoord().y - in.getCoord().y) / felm.getLength();
						
						double d = force.getCoord().x;
						double x1 = in.getCoord().x + d*cos2;
						double y1 = in.getCoord().y + d*sin2;
						
						po = new Point2D.Double(x1, y1);
						p = view.getDrawingArea().getViewPoint(po);
						concForcesPoints.add(new PointDraw(p, felm));
						
						//Fx loads
						if (force.getForce(0) != 0) {
							Draw draw = new ArrowDraw.Out();
							draw.setRepresents(felm);
							((ArrowDraw)draw).setValue(force.getForce(0));
							draw.setAngle(elmAngle);
							draw.setLocation(view.getDrawingArea().getViewPoint(new Point2D.Double(x1, y1)));
							//draw.setLabel(String.valueOf(force.getForce(0)));
							concForces.add(draw);
						}
						//Fy loads
						if (force.getForce(1) != 0) {
							Draw draw = new ArrowDraw.Out();
							draw.setRepresents(felm);
							((ArrowDraw)draw).setValue(force.getForce(1));
							double forceAngle = elmAngle + Math.toRadians(90);
							draw.setAngle(forceAngle);
							draw.setLocation(view.getDrawingArea().getViewPoint(new Point2D.Double(x1, y1)));
							//draw.setLabel(String.valueOf(force.getForce(1)));
							this.add(draw);
						}
						//Mz loads
						if (force.getForce(5) != 0) {
							Draw draw = new ArrowDraw.AntiClockwise();
							draw.setRepresents(felm);
							((ArrowDraw)draw).setValue(force.getForce(5));
							draw.setLocation(view.getDrawingArea().getViewPoint(new Point2D.Double(x1, y1)));
							this.add(draw);
						}
					}//end of adding conc forces
					
					//Adding pre-strains
					if (felm.getElmPreDisplacement(0) != 0){
						Draw draw = new DisplaceDraw.Linear();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(0));
						preStrains.add(draw);
					}
					if (felm.getElmPreDisplacement(1) != 0){
						Draw draw = new DisplaceDraw.Linear();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(90));
						draw.setLocation(p1);
						((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(1));
						preStrains.add(draw);
					}
					if (felm.getElmPreDisplacement(5) != 0){
						Draw draw = new DisplaceDraw.Angular();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(5));
						preStrains.add(draw);
					}
					if (felm.getElmPreDisplacement(6) != 0){
						Draw draw = new DisplaceDraw.Linear();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p2);
						((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(6));
						preStrains.add(draw);
					}
					if (felm.getElmPreDisplacement(7) != 0){
						Draw draw = new DisplaceDraw.Linear();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle + Math.toRadians(90));
						draw.setLocation(p2);
						((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(7));
						preStrains.add(draw);
					}
					if (felm.getElmPreDisplacement(11) != 0){
						Draw draw = new DisplaceDraw.Angular();
						draw.setRepresents(felm);
						draw.setAngle(elmAngle);
						draw.setLocation(p2);
						((DisplaceDraw)draw).setValue(felm.getElmPreDisplacement(11));
						preStrains.add(draw);
					}
					//end of adding pre-strains
					
					//Adding initial equivalent nodal forces
					if (felm.getInitialNodalForce(0) != 0) {
						Draw draw = new ArrowDraw.Out();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(felm.getInitialNodalForce(0));
						draw.setAngle(elmAngle);
						draw.setLocation(p1);
						iniEqForces.add(draw);
					}
					if (felm.getInitialNodalForce(1) != 0) {
						Draw draw = new ArrowDraw.Out();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(felm.getInitialNodalForce(1));
						draw.setAngle(elmAngle + Math.toRadians(90));
						draw.setLocation(p1);
						iniEqForces.add(draw);
					}
					if (felm.getInitialNodalForce(5) != 0) {
						Draw draw = new ArrowDraw.AntiClockwise();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(felm.getInitialNodalForce(5));
						draw.setLocation(p1);
						iniEqForces.add(draw);
					}
					if (felm.getInitialNodalForce(6) != 0) {
						Draw draw = new ArrowDraw.Out();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(felm.getInitialNodalForce(6));
						draw.setAngle(elmAngle);
						draw.setLocation(p2);
						iniEqForces.add(draw);
					}
					if (felm.getInitialNodalForce(7) != 0) {
						Draw draw = new ArrowDraw.Out();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(felm.getInitialNodalForce(7));
						draw.setAngle(elmAngle + Math.toRadians(90));
						draw.setLocation(p2);
						iniEqForces.add(draw);
					}
					if (felm.getInitialNodalForce(11) != 0) {
						Draw draw = new ArrowDraw.AntiClockwise();
						draw.setRepresents(felm);
						((ArrowDraw)draw).setValue(felm.getInitialNodalForce(11));
						draw.setLocation(p2);
						iniEqForces.add(draw);
					}
					//End of adding initial equivalent nodal forces
					
					//Adding temperature changes
					if (felm.getDeltaTemp(0) != 0) {
						Draw draw = new StringDraw();
						draw.setRepresents(felm);
						((StringDraw)draw).setString("Ts = " + String.valueOf(felm.getDeltaTemp(0)));
						int x = (int) ((p1.getX() + p2.getX())/2);
						int y = (int) ((p1.getY() + p2.getY())/2);
						draw.setAngle(elmAngle);
						((StringDraw)draw).setCentre(new Point(x, y));
						draw.setLocation(new Point(x, y-6));
						tempChanges.add(draw);
					}
					if (felm.getDeltaTemp(1) != 0) {
						Draw draw = new StringDraw();
						draw.setRepresents(felm);
						((StringDraw)draw).setString("Tn = " + String.valueOf(felm.getDeltaTemp(1)));
						int x = (int) ((p1.getX() + p2.getX())/2);
						int y = (int) ((p1.getY() + p2.getY())/2);
						draw.setAngle(elmAngle);
						((StringDraw)draw).setCentre(new Point(x, y));
						draw.setLocation(new Point(x, y+4));
						tempChanges.add(draw);
					}
					if (felm.getDeltaTemp(2) != 0) {
						Draw draw = new StringDraw();
						draw.setRepresents(felm);
						((StringDraw)draw).setString("Ti = " + String.valueOf(felm.getDeltaTemp(2)));
						int x = (int) ((p1.getX() + p2.getX())/2);
						int y = (int) ((p1.getY() + p2.getY())/2);
						draw.setAngle(elmAngle);
						((StringDraw)draw).setCentre(new Point(x, y));
						draw.setLocation(new Point(x, y+14));
						tempChanges.add(draw);
					}
					//End of adding temperature changes
					
					//Adding distributed loads
					ListIterator dfs = felm.getElmLineForcesList().listIterator();
					while (dfs.hasNext()) {
						ElementForce force = (ElementForce)dfs.next();
						
						//Setting the application points of this distributed force
						double cos2 = (fn.getCoord().x - in.getCoord().x) / felm.getLength();
						double sin2 = (fn.getCoord().y - in.getCoord().y) / felm.getLength();
						
						double d1 = ((PointForce)force.getPointForcesList().get(0)).getCoord().x;
						double d2 = ((PointForce)force.getPointForcesList().get(1)).getCoord().x;
						double x1 = in.getCoord().x + d1*cos2;
						double y1 = in.getCoord().y + d1*sin2;
						double x2 = in.getCoord().x + d2*cos2;
						double y2 = in.getCoord().y + d2*sin2;
						
						//Setting the values of a, b, axvalue, bxvalue, ayvalue and byvalue
						double a = ((PointForce)force.getPointForcesList().get(0)).getCoord().x;
						double b = ((PointForce)force.getPointForcesList().get(1)).getCoord().x;
						double axvalue = ((PointForce)force.getPointForcesList().get(0)).getForce(0);
						double bxvalue = ((PointForce)force.getPointForcesList().get(1)).getForce(0);
						double ayvalue = ((PointForce)force.getPointForcesList().get(0)).getForce(1);
						double byvalue = ((PointForce)force.getPointForcesList().get(1)).getForce(1);
						
						//Fx loads
						if (axvalue != 0 || bxvalue != 0) {
							po = new Point2D.Double(x1, y1);
							Point pa = view.getDrawingArea().getViewPoint(po);
							po = new Point2D.Double(x2, y2);
							Point pb = view.getDrawingArea().getViewPoint(po);
							pa.y = pa.y + 5;
							pb.y = pb.y + 5;
							Draw draw = new LineArrowDraw.X();
							draw.setRepresents(felm);
							((LineArrowDraw)draw).setBase(new LineDraw(pa, pb));
							((LineArrowDraw)draw).setA(a);
							((LineArrowDraw)draw).setB(b);
							((LineArrowDraw)draw).setAValue(axvalue);
							((LineArrowDraw)draw).setBValue(bxvalue);
							draw.setAngle(Math.toRadians(0));
							draw.setLocation(pa);
							((LineArrowDraw)draw).setEndLocation(pb);
							distForces.add(draw);
						}
						//Fy loads
						if (ayvalue != 0 || byvalue != 0) {
							po = new Point2D.Double(x1, y1);
							Point pa = view.getDrawingArea().getViewPoint(po);
							po = new Point2D.Double(x2, y2);
							Point pb = view.getDrawingArea().getViewPoint(po);
							Draw draw = new LineArrowDraw.Y();
							draw.setRepresents(felm);
							((LineArrowDraw)draw).setBase(new LineDraw(pa, pb));
							((LineArrowDraw)draw).setA(a);
							((LineArrowDraw)draw).setB(b);
							((LineArrowDraw)draw).setAValue(ayvalue);
							((LineArrowDraw)draw).setBValue(byvalue);
							draw.setAngle(Math.toRadians(90));
							draw.setLocation(pa);
							((LineArrowDraw)draw).setEndLocation(pb);
							distForces.add(draw);
						}
					}//End of distributed loads
				}//end of felements
				
				//Filling the pelements list
				else if (elm instanceof ParametricElement) {
					ParElementDraw eDraw = new ParElementDraw(view.getDrawingArea(),elm);
					pelements.add(eDraw);
					
//					Adding distributed loads
					ElementSide elmSide = new ElementSide((ParametricElement)elm);
					elmSide.mountSide();
					Side sd = (Side)elmSide.getSidesList().get(0);
					
					
					ListIterator lineForces = elm.getElmLineForcesList().listIterator();
					while (lineForces.hasNext()) {
						
						
						ElementForce force = (ElementForce)lineForces.next();
						
						PointForce pf1 = new PointForce();
						PointForce pf2 = new PointForce();
									
									if (sd.getNNodes()==2){
									
									pf1 = (PointForce)force.getPointForcesList().get(0);
									pf2 = (PointForce)force.getPointForcesList().get(1);
									
									}
									
									if (sd.getNNodes()==3){
										
										pf1 = (PointForce)force.getPointForcesList().get(0);
										pf2 = (PointForce)force.getPointForcesList().get(2);
										
									}
									
									if (sd.getNNodes()==4){
										
										pf1 = (PointForce)force.getPointForcesList().get(0);
										pf2 = (PointForce)force.getPointForcesList().get(3);
										
									}
									
									double Fx1 = pf1.getForce(0);
									double Fy1 = pf1.getForce(1);
									double Mz1 = pf1.getForce(5);
									double Fx2 = pf2.getForce(0);
									double Fy2 = pf2.getForce(1);
									double Mz2 = pf2.getForce(5);
									
									if (pf1.getLabel()!=null && pf2.getLabel()!=null){
										
																
									if ( Fx1!=0 || Fx2!=0 ) {
									//if ( Fx1!=0) {
										Point pt1 = view.getDrawingArea().getViewPoint( new Point2D.Double(pf1.getCoord().x, pf1.getCoord().y) );
										Point pt2 = view.getDrawingArea().getViewPoint( new Point2D.Double(pf2.getCoord().x, pf2.getCoord().y) );
										Draw draw = new ArrowLineDraw.X( pt1, pt2 );
										//Draw draw = new PointDraw( pt1);
										((ArrowLineDraw)draw).setAValue(Fx1);
										((ArrowLineDraw)draw).setBValue(Fx2);
										draw.setLabel( force.getLabel() );
										draw.setRepresents(elm);
										distForces.add(draw);
										//this.add(draw);
									}
							
									if ( Fy1!=0 || Fy2!=0 ) {
									//if ( Fy1!=0 ) {
										Point pt1 = view.getDrawingArea().getViewPoint( new Point2D.Double(pf1.getCoord().x, pf1.getCoord().y) );
										Point pt2 = view.getDrawingArea().getViewPoint( new Point2D.Double(pf2.getCoord().x, pf2.getCoord().y) );
										Draw draw = new ArrowLineDraw.Y( pt1, pt2 );
										//Draw draw = new PointDraw( pt1);
										((ArrowLineDraw)draw).setAValue(Fy1);
										((ArrowLineDraw)draw).setBValue(Fy2);
										draw.setLabel( force.getLabel() );
										draw.setRepresents(elm);
										distForces.add(draw);
										//this.add(draw);
									}
									
									if ( Mz1!=0 || Mz2!=0 ) {
									//if ( Mz1!=0 ) {
										Point pt1 = view.getDrawingArea().getViewPoint( new Point2D.Double(pf1.getCoord().x, pf1.getCoord().y) );
										Point pt2 = view.getDrawingArea().getViewPoint( new Point2D.Double(pf2.getCoord().x, pf2.getCoord().y) );
										Draw draw = new ArrowLineDraw.Z( pt1, pt2 );
										//Draw draw = new PointDraw( pt1);
										((ArrowLineDraw)draw).setAValue(Mz1);
										((ArrowLineDraw)draw).setBValue(Mz2);
										draw.setLabel( force.getLabel() );
										distForces.add(draw);
										//this.add(draw);
									}
								}			
								
		}//End of distributed loads
					
					ArrayList incid = elm.getIncidence();
					ListIterator nds = incid.listIterator();
					while(nds.hasNext()) {
						Node nd = (Node)nds.next();
						IPoint3d p3d = nd.getCoord();
						double angle = Math.atan2( (p3d.y-eDraw.getYMedium()), (p3d.x-eDraw.getXMedium()) );
						nd.setAngle(angle);
					}
				}//end of pelements
				
			}//end of elements
			
		}
		

	
	
	public void draw(Graphics2D g) {
        
		double nodeScale = view.getViewState().nodeScale;
		double supportScale = view.getViewState().supportScale;
		double loadScale = view.getViewState().loadScale;
		double displaceScale = view.getViewState().displaceScale;
		double concForcePointScale = view.getViewState().concForcePointScale;
		double preStrainsScale = view.getViewState().preStrainsScale;
		double iniEqForceScale = view.getViewState().iniEqForceScale;
		
        g.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
		
		Draw draw;
		
		Node no;
		
		//Draws global axis if selected
		if (view.getViewState().getViewGlobalAxis()) {
			g.setColor(view.getViewState().globalAxisColor);
			draw = new AxisDraw();
			((AxisDraw)draw).setLabel1("X");
			((AxisDraw)draw).setLabel2("Y");
			draw.setLocation(new Point(10, view.getDrawingArea()
					.getHeight()-10));
			draw.draw(g);
		}
		
		//Draws frame elements
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			g.setColor(view.getViewState().lineColor);
			draw = (Draw)lns.next();
			draw.draw(g);
		}
		
		//Draws local axis
		if (view.getViewState().getViewLocalAxis()) {
			ListIterator la = localAxis.listIterator();
			while(la.hasNext()) {
				g.setColor(view.getViewState().localAxisColor);
				draw = (Draw)la.next();
				draw.draw(g);
			}
		} 
		
		//Draws parametric elements
		ParElementDraw eDraw;
		ListIterator els = pelements.listIterator();
		while(els.hasNext()) {
			eDraw = (ParElementDraw)els.next();
			g.setColor( view.getViewState().parelementColor );
			if ( (((ParametricElement)eDraw.getRepresents()).getMaterial()) != null ) {
				//g.setColor( view.getViewState().getColor(index) );
				g.setColor(((ParametricElement)eDraw.getRepresents()).getMaterial().getColor() );
			}
			eDraw.draw(g);
		}
		els = pelements.listIterator();
		while(els.hasNext()) {
			eDraw = (ParElementDraw)els.next();
			g.setColor( view.getViewState().boundaryElementColor );
			eDraw.drawBoundary(g);
			if ( view.getViewState().getViewElementLabel() ) {
				g.setColor( Color.black );
				eDraw.drawLabel(g);
			}
		}
		
		//Draws supports
		g.setColor(view.getViewState().supportColor);
		ListIterator sts = supports.listIterator();
		while(sts.hasNext()) {
			draw = (Draw)sts.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(view.getDrawingArea().getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(supportScale);
			draw.draw(g);
		}
		
		//Draws liberations
		g.setColor(view.getViewState().supportColor);
		ListIterator libs = liberations.listIterator();
		while(libs.hasNext()) {
			draw = (Draw)libs.next();
			draw.setScale(supportScale);
			draw.draw(g);
		}
		
		//Draws initial equivalent nodal forces
		g.setColor(view.getViewState().iniEqForceColor);
		ListIterator ies = iniEqForces.listIterator();
		while(ies.hasNext()) {
			draw = (Draw)ies.next();
			draw.setScale(iniEqForceScale);
			draw.draw(g);
		}
		
		//Draws temperature changes
		g.setColor(view.getViewState().tempChangeColor);
		ListIterator tcs = tempChanges.listIterator();
		while(tcs.hasNext()) {
			draw = (Draw)tcs.next();
			draw.draw(g);
		}
		
		//Draws prescribed displacements
		g.setColor(view.getViewState().displaceColor);
		ListIterator dds = displaces.listIterator();
		while(dds.hasNext()) {
			draw = (Draw)dds.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(view.getDrawingArea().getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(displaceScale);
			draw.draw(g);
		}
		
		//Draws pre-strains
		g.setColor(view.getViewState().preStrainsColor);
		ListIterator pss = preStrains.listIterator();
		while(pss.hasNext()) {
			draw = (Draw)pss.next();
			draw.setScale(preStrainsScale);
			draw.draw(g);
		}
		
		//Draws springs
		g.setColor(view.getViewState().springColor);
		ListIterator sps = springs.listIterator();
		while(sps.hasNext()) {
			draw = (Draw)sps.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(view.getDrawingArea().getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(supportScale);
			draw.draw(g);
		}
		
		//Draws nodal loads
		g.setColor(view.getViewState().loadColor);
		ListIterator nls = nodalLoads.listIterator();
		while(nls.hasNext()) {
			draw = (Draw)nls.next();
			no = (Node)draw.getRepresents();
			IPoint3d p3 = no.getCoord();
			draw.setLocation(view.getDrawingArea().getViewPoint( new Point2D.Double(p3.x, p3.y) ));
			draw.setScale(loadScale);
			draw.draw(g);
		}
		
		//Draws nodes
		g.setColor(view.getViewState().pointColor);
		ListIterator pts = nodes.listIterator();
		while(pts.hasNext()) {
			draw = (Draw)pts.next();
			no = (Node)draw.getRepresents();
			if (view.getViewState().getViewNodeLabel())
				draw.setLabel(no.getLabel());
			else draw.setLabel("");
			if (model.getGlobalAnalysisModel().getType().equals("PlaneTruss")){
				g.setColor(view.getViewState().pointColor);
				draw.setScale(nodeScale*2);
				draw.draw(g);
				Draw draw2 = (Draw)draw.clone();
				g.setColor(view.getViewState().getBackground());
				draw2.setScale(nodeScale*1);
				draw2.setSelected(false);
				draw2.setSelectable(true);
				draw2.draw(g);
			} else {
				draw.setScale(nodeScale*1);
				draw.draw(g);
			}
		}
		
		//Draws concentrated forces
		g.setColor(view.getViewState().loadColor);
		ListIterator cfs = concForces.listIterator();
		while(cfs.hasNext()) {
			draw = (Draw)cfs.next();
			draw.setScale(loadScale);
			draw.draw(g);
		}
		
		//Draws concentrated forces points
		g.setColor(view.getViewState().concForcePointColor);
		ListIterator cfps = concForcesPoints.listIterator();
		while(cfps.hasNext()) {
			draw = (Draw)cfps.next();
			draw.setScale(concForcePointScale);
			draw.draw(g);
		}
		
		//Draws distributed forces
		g.setColor(view.getViewState().distributedLoadColor);
		ListIterator dfs = distForces.listIterator();
		while(dfs.hasNext()) {
			draw = (Draw)dfs.next();
			draw.setScale(loadScale);
			draw.draw(g);
		}
		
	}
	public void fit() {
        
        //Calculating bounds
        if (nodes.size() >= 2){
            Point leftUp = new Point();
            Point rightDown = new Point();
            PointDraw po;
            ListIterator pts = nodes.listIterator();
            po = (PointDraw)pts.next();
            leftUp.x = po.getLocation().x;
            leftUp.y = po.getLocation().y;
            rightDown.x = po.getLocation().x;
            rightDown.y = po.getLocation().y;
            while (pts.hasNext()){
                po = (PointDraw)pts.next();
                if (po.getLocation().x < leftUp.x){
                    leftUp.x = po.getLocation().x;
                }
                if (po.getLocation().x > rightDown.x){
                    rightDown.x = po.getLocation().x;
                }
                if (po.getLocation().y < leftUp.y){
                    leftUp.y = po.getLocation().y;
                }
                if (po.getLocation().y > rightDown.y){
                    rightDown.y = po.getLocation().y;
                }
            }
			
            //Adding some border
            leftUp.x = leftUp.x - 15;
            leftUp.y = leftUp.y - 15;
            rightDown.x = rightDown.x + 15;
            rightDown.y = rightDown.y + 15;
            
            Point2D p1 = view.getDrawingArea().getWorldPoint(leftUp);
            Point2D p2 = view.getDrawingArea().getWorldPoint(rightDown);
            Rectangle2D r = new Rectangle2D.Double(p1.getX(), p2.getY(), p2.getX(), p1.getY());
            
            view.getDrawingArea().setZoom(r);
        }
    }
	
	public void add(Object obj) {
		
		if (obj instanceof SpringDraw) {
			SpringDraw sd = (SpringDraw)obj;
			Node no = (Node)sd.getRepresents();
			IPoint3d p3 = no.getCoord();
			sd.setLocation( view.getDrawingArea().getViewPoint(new Point2D.Double(p3.x, p3.y)) );
			springs.add(sd);
		}
		
		if (obj instanceof DisplaceDraw) {
			DisplaceDraw dd = (DisplaceDraw)obj;
			Node no = (Node)dd.getRepresents();
			IPoint3d p3 = no.getCoord();
			dd.setLocation( view.getDrawingArea().getViewPoint(new Point2D.Double(p3.x, p3.y)) );
			displaces.add(dd);
		}
		
		if (obj instanceof SupportDraw) {
			SupportDraw s = (SupportDraw)obj;
			Node no = (Node)s.getRepresents();
			if (no != null){
				IPoint3d p3 = no.getCoord();
				s.setLocation(view.getDrawingArea().getViewPoint( new Point2D.Double(p3.x, p3.y) ));
				supports.add(s);
			}
		}
		
		if (obj instanceof ArrowDraw) {
			ArrowDraw a = (ArrowDraw)obj;
			
			Object obj2 = a.getRepresents();
			if (obj2 instanceof Node) {
				Node no = (Node)a.getRepresents();
				if (no != null){
					IPoint3d p3 = no.getCoord();
					a.setLocation(view.getDrawingArea().getViewPoint( new Point2D.Double(p3.x, p3.y) ));
					nodalLoads.add(a);
				}
			}
			else if (obj2 instanceof FrameElement) {
				concForces.add(a);
			}
		}
		
	}
	
	
	public void remove(Object obj) {}
	
	
	public void removeAll() {
        nodes.clear();
		felements.clear();
		pelements.clear();
		
		supports.clear();
		nodalLoads.clear();
		springs.clear();
		displaces.clear();
		
		localAxis.clear();
		concForces.clear();
		concForcesPoints.clear();
		liberations.clear();
		preStrains.clear();
		distForces.clear();
		tempChanges.clear();
		iniEqForces.clear();
		elasticConnections.clear();
		
		gaussMarks.clear();
    }
	
	public boolean isSelected() {
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.isSelected()) {
                return true;
            }
        }
        ListIterator gpts = gaussMarks.listIterator();
        while(gpts.hasNext()) {
            draw = (Draw)gpts.next();
            if (draw.isSelected()) {
                return true;
            }
        }
        
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.isSelected()){
				return true;
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.isSelected()){
				return true;
			}
		}
		
		return false;
	}
	
	
	 
	
	public void select(Point p){}
	
	 
	
	public void selectAll(){}
	 
	
	public void unSelectAll(){
	    
	}
	 
	public void unSelectPoints() {
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            draw.setSelected(false);
        }
        ListIterator gpts = gaussMarks.listIterator();
        while(gpts.hasNext()) {
            draw = (Draw)gpts.next();
            draw.setSelected(false);
        }
	}
	 
	
	
	
	public boolean contains(Point2D po) {
        Point p = view.getDrawingArea().getViewPoint(po);
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.contains(p)) {
                return true;
            }
        }
        
        ListIterator gpts = gaussMarks.listIterator();
        while(gpts.hasNext()) {
            draw = (Draw)gpts.next();
            if (draw.contains(p)) {
                return true;
            }
        }
        
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.contains(p)) {
				return true;
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.contains(p)) {
				return true;
			}
		}
        return false;
    }
	
	 public boolean contains(Line2D l) {
        Point  p1 = view.getDrawingArea().getViewPoint(l.getP1());
        Point  p2 = view.getDrawingArea().getViewPoint(l.getP2());
        Draw draw;
        
        ListIterator lns = felements.listIterator();
        while(lns.hasNext()) {
            draw = (Draw)lns.next();
            if (draw.contains(p1) && draw.contains(p2)) {
                return true;
            }
        }
        ListIterator pes = pelements.listIterator();
        while(pes.hasNext()) {
            draw = (Draw)pes.next();
            if (draw.contains(p1) && draw.contains(p2)) {
                return true;
            }
        }
		
        return false;
    }
	
	
	//public  boolean contains(IPoint3d po) {}
	 
	
	
	 public Object get(Point2D po) {
		Point location = view.getDrawingArea().getViewPoint(po);
        Draw draw;
        
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.contains(location)) {
                return draw.getRepresents();
            }
        }
        ListIterator gpts = gaussMarks.listIterator();
        while(gpts.hasNext()) {
            draw = (Draw)gpts.next();
            if (draw.contains(location)) {
                return draw.getRepresents();
            }
        }
        
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.contains(location)){
				return draw.getRepresents();
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.contains(location)){
				return draw.getRepresents();
			}
		}
		
        return null;
    } 
	
	public ArrayList getSelection() {
        return selection;
    }
	
	public Point pick (Point p) {
        
        Draw draw;
		
        ListIterator pts = nodes.listIterator();
        while(pts.hasNext()) {
            draw = (Draw)pts.next();
            if (draw.contains(p)) {
                return draw.getLocation();
            }
        }
        
        ListIterator gpts = gaussMarks.listIterator();
        while(gpts.hasNext()) {
            draw = (Draw)gpts.next();
            if (draw.contains(p)) {
                return draw.getLocation();
            }
        }
		ListIterator lns = felements.listIterator();
		while(lns.hasNext()) {
			draw = (Draw)lns.next();
			if (draw.contains(p)) {
				return draw.getLocation();
			}
		}
		ListIterator pes = pelements.listIterator();
		while(pes.hasNext()) {
			draw = (Draw)pes.next();
			if (draw.contains(p)) {
				return draw.getLocation();
			}
		}
        return p;
    }
   
	public ArrayList<Draw> getEquations() {
        return null;
    }
	
	
}
